﻿using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ClassLibrary_fqy_NET.SocketHelper
{
    public class UdpAsync
    {
        private const int MaxLength = 2048;
        private Socket? worksocket;

        /// <summary>
        /// 数据接收委托
        /// </summary>
        /// <param name="buff"></param>
        public delegate void OnReceiveData(byte[] buff, IPEndPoint remote);
        /// <summary>
        /// 数据接收事件
        /// </summary>
        public event OnReceiveData? ReceiveSeverData;
        /// <summary>
        /// 初始化绑定
        /// </summary>
        public UdpAsync()
        {
            Bind(IPAddress.Any, 0);
        }
        /// <summary>
        /// 绑定本地IPEndPoint
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public void Bind(IPAddress ip, int port)
        {

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPEndPoint endPoint = new IPEndPoint(ip, port);
            socket.Bind(endPoint);
            worksocket = socket;
            ReceiveAsync(endPoint);
        }

        private async void ReceiveAsync(IPEndPoint remote)
        {
            byte[] buff = new byte[MaxLength];
            try
            {
                var result = await worksocket!.ReceiveFromAsync(buff, SocketFlags.None, remote);
                if (result.ReceivedBytes > 0)
                {
                    byte[] data = new byte[result.ReceivedBytes];
                    Array.Copy(buff, data, result.ReceivedBytes);
                    ReceiveSeverData!(data, (IPEndPoint)result.RemoteEndPoint);
                }
            }
            catch (Exception)
            {
                remote = new IPEndPoint(IPAddress.Any, 0);
            }
            ReceiveAsync(remote);
        }
        /// <summary>
        /// 异步发送数据
        /// </summary>
        /// <param name="data">发送的数据</param>
        /// <param name="endPoint">远程目标endPoint</param>
        /// <returns></returns>
        public async Task<int> SendAsync(byte[] data, IPEndPoint endPoint)
        {
            var result = 0;
            if (worksocket != null)
            {
                result = await worksocket.SendToAsync(data, SocketFlags.None, endPoint);
                return result;
            }
            return result;
        }
        /// <summary>
        /// 异步发送数据
        /// </summary>
        /// <param name="strdata">发送的字符串</param>
        /// <param name="endPoint">远程目标endPoint</param>
        /// <returns></returns>
        public async Task<int> SendAsync(string strdata, IPEndPoint endPoint)
        {
            byte[] data = Encoding.ASCII.GetBytes(strdata);
            var result = 0;
            if (worksocket != null)
            {
                result = await worksocket.SendToAsync(data, SocketFlags.None, endPoint);
                return result;
            }
            return result;
        }





    }
}
